package com.mes.common.util;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Projections;

import com.bstek.dorado.data.provider.Page;;

public class MMPage<T> {
	
	private Page<T> page;
	
	public MMPage(Page<T> page) {
		this.page = page;
	}

	public List<T> pagePro(final Query query, final Query countQuery) {
		
		int safePageSize = page.getPageSize() < 1 ? 65535 : page.getPageSize();
		int start = (page.getPageNo() - 1) * safePageSize;
		List<T> list = query.setMaxResults(safePageSize).setFirstResult(start).list();
		page.setEntities(list);
		
		int count = 0;
		if (countQuery != null) {
			Object countObj = countQuery.uniqueResult();
			if (countObj instanceof Long) {
				count = ((Long) countObj).intValue();
			} else if (countObj instanceof Integer) {
				count = ((Integer) countObj).intValue();
			}
		}
		page.setEntityCount(count);
		
		return list;
		
	}
	
	public List<T> pagePro(final Query query) {
		return this.pagePro(query, null);
	}

	public List<T> pagePro(Criteria criteria) {
		int totalCount = 0;
		Object totalObject = criteria.setProjection(Projections.rowCount()).uniqueResult();
		if (totalObject instanceof Integer) {
			totalCount = (Integer) totalObject;
		} else if (totalObject instanceof Long) {
			totalCount = ((Long) totalObject).intValue();
		} else if (totalObject != null) {
			throw new RuntimeException("Can not convert [" + totalObject
					+ "] to a int value when query entity total count!");
		}
		page.setEntityCount(totalCount);

		criteria.setProjection(null);
		criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		
		int start = (page.getPageNo() - 1) * page.getPageSize();
		List<T> list = criteria.setFirstResult(start).setMaxResults(page.getPageSize()).list();
		page.setEntities(list);
		
		return list;
	}


}
